/**
 * 
 */
package pe.bf.extranet.dao.impl;

import java.math.BigInteger;
import java.sql.CallableStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

import javax.sql.DataSource;

import oracle.jdbc.OracleTypes;

import org.apache.log4j.Logger;

import pe.bf.base.dao.impl.BaseDAOImpl;
import pe.bf.base.types.OutParameter;
import pe.bf.domain.bean.Empleado;
import pe.bf.domain.bean.Moneda;
import pe.bf.domain.bean.SolicitudCreacion;
import pe.bf.domain.bean.TipoCuenta;
import pe.bf.domain.bean.TipoDocumento;
import pe.bf.domain.exceptions.DomainException;
import pe.bf.extranet.dao.SolicitudCreacionDAO;

/**
 * rfigueroa
 * 
 */
public class SolicitudCreacionDAOImpl extends BaseDAOImpl implements
		SolicitudCreacionDAO {

	Logger logger = Logger.getLogger(SolicitudCreacionDAOImpl.class);

	private static final String USP_CRE_SOLIC_CREACION = "{call PGK_SOLICITUDCREACION.USP_CRE_SOLIC_CREACION(?,?,?,?,?,?,?,?,?)}";
	private static final String USP_CRE_EMPLEADO = "{call PGK_SOLICITUDCREACION.USP_CRE_EMPLEADO(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)}";
	private static final String USP_ACT_SOLIC_CREACION = "{call PGK_SOLICITUDCREACION.USP_ACT_SOLIC_CREACION(?,?,?,?)}";
	private static final String USP_ELI_SOLIC_CREACION = "{call PGK_SOLICITUDCREACION.USP_ELI_SOLIC_CREACION(?)}";
	private static final String USP_LIS_SOLIC_CREACION = "{call PGK_SOLICITUDCREACION.USP_LIS_SOLIC_CREACION(?)}";
	private static final String USP_LIS_SOLIC_CREAC_EMPRESA = "{call PGK_SOLICITUDCREACION.USP_LIS_SOLIC_CREAC_EMPRESA(?,?)}";
	private static final String USP_LIS_DET_SOLIC_CREACION = "{call PGK_SOLICITUDCREACION.USP_LIS_DET_SOLIC_CREACION(?,?,?)}";

	/**
	 * 
	 * @param dataSource
	 */
	public SolicitudCreacionDAOImpl(DataSource dataSource) {
		super(dataSource);
	}

	@SuppressWarnings("finally")
	@Override
	public List<String> createSolicitudCreacion(
			SolicitudCreacion solicitudCreacion) throws DomainException {
		List<String> errores = new ArrayList<String>();
		try {
			solicitudCreacion.setIdSolicitudCreacion(invokeStoreProcedureGetId(
					USP_CRE_SOLIC_CREACION, solicitudCreacion
							.getNombreArchivo(), solicitudCreacion.getEmpresa()
							.getIdEmpresa(), solicitudCreacion.getTipoCuenta()
							.getIdTipocuenta(), solicitudCreacion
							.getUsuarioCreacion(), solicitudCreacion
							.getNroRegistros(), solicitudCreacion.getMoneda()
							.getIdMoneda(), solicitudCreacion.getAdjunto(),
					solicitudCreacion.getFechaCreacionArchivo(),
					new OutParameter(OracleTypes.VARCHAR)));

			errores = createDetalleSolicitudCreacion(
					(List<Empleado>) solicitudCreacion.getListaEmpleados(),
					solicitudCreacion.getIdSolicitudCreacion(),
					solicitudCreacion.getEmpresa().getIdEmpresa());

			return errores;
		} catch (Exception e) {
			e.printStackTrace();
			errores.add("Error al grabar cabecera =" + e.getMessage());
			throw new DomainException(e);
		} finally {
			return errores;
		}
	}

	@Override
	public List<String> createDetalleSolicitudCreacion(List<Empleado> detalle,
			long id, long empresa) throws DomainException {
		List<String> errores = new ArrayList<String>();

		if (id == -1) {
			return errores;
		}

		DateFormat df = new SimpleDateFormat("dd/MM/yyyy");
		for (Empleado empleado : detalle) {
			try {
				invokeStoreProcedure(USP_CRE_EMPLEADO, id,
						empleado.getApellidonombre(), empleado.getDireccion(),
						empleado.getEstadocivil(), empleado.getNrocuenta(),
						empleado.getNrodocumento(), empleado.getOcupacion(),
						empleado.getSexo(), empleado.getTelefono(),
						empleado.getUbigeo(), empleado.getUsuariocreacion(),
						empleado.getDistrito(), empresa, empleado.getMoneda()
								.getIdMoneda(), empleado.getTipocuenta()
								.getIdTipocuenta(), empleado.getTipodocumento()
								.getIdTipodocumento(), df.format(empleado
								.getFechanacimiento()));
			} catch (Exception e) {
				errores.add("Empleado " + empleado.getNrodocumento()
						+ " con errror" + e.getMessage());
				e.printStackTrace();
			}
		}
		return errores;

	}

	@Override
	public void actualizarSolicitudCreacion(SolicitudCreacion solicitudCreacion)
			throws DomainException {
		invokeStoreProcedure(USP_ACT_SOLIC_CREACION,
				solicitudCreacion.getIdSolicitudCreacion(),
				solicitudCreacion.getEstado(),
				solicitudCreacion.getUsuarioModificacion(),
				solicitudCreacion.getFechaEjecucionbf());
	}

	@Override
	public void eliminarSolicitudCreacion(SolicitudCreacion solicitudCreacion)
			throws DomainException {
		invokeStoreProcedure(USP_ELI_SOLIC_CREACION,
				solicitudCreacion.getIdSolicitudCreacion());
	}

	@Override
	public List<SolicitudCreacion> listarSolicitudCreacion()
			throws DomainException {

		ResultSet resultSet = invokeStoreProcedureRs(USP_LIS_SOLIC_CREACION,
				new OutParameter(OracleTypes.CURSOR));
		List<SolicitudCreacion> solicitudCreacionList = new ArrayList<SolicitudCreacion>();
		SolicitudCreacion solicitudCreacion = new SolicitudCreacion();
		try {
			while (resultSet.next()) {
				solicitudCreacion = new SolicitudCreacion();
				solicitudCreacion.setIdSolicitudCreacion(resultSet
						.getLong("ID_SOLICITUDCREACION"));
				solicitudCreacion.setEstado(resultSet.getString("ESTADO"));
				solicitudCreacion.setFechaCreacion(resultSet
						.getDate("FECHACREACION"));
				solicitudCreacion.setFechaEjecucionbf(resultSet
						.getDate("FECHAEJECUCIONBF"));
				solicitudCreacion.setNombreArchivo(resultSet
						.getString("NOMBREARCHIVO"));
				solicitudCreacion
						.setMoneda(new Moneda(Long.valueOf(resultSet
								.getString("ID_MONEDA")), resultSet
								.getString("MONEDA")));
				solicitudCreacion.setTipoCuenta(new TipoCuenta(Long
						.valueOf(resultSet.getString("ID_TIPOCUENTA")),
						resultSet.getString("TIPOCUENTA")));
				solicitudCreacionList.add(solicitudCreacion);
			}
		} catch (SQLException e) {
			logger.error(e, e.fillInStackTrace());
			throw new DomainException(e);
		}
		close(resultSet);
		return solicitudCreacionList;
	}

	@Override
	public List<SolicitudCreacion> listarSolicitudCreacionPorEmpresa(
			BigInteger codigoEmpresa) throws DomainException {

		CallableStatement cal = invokeStoreProcedureCallable(
				USP_LIS_SOLIC_CREAC_EMPRESA, codigoEmpresa + "",
				new OutParameter(OracleTypes.CURSOR));
		ResultSet resultSet = null;
		List<SolicitudCreacion> solicitudCreacionList = new ArrayList<SolicitudCreacion>();

		try {
			resultSet = (ResultSet) cal.getObject(2);
			while (resultSet.next()) {
				SolicitudCreacion solicitudCreacion = new SolicitudCreacion();
				solicitudCreacion.setIdSolicitudCreacion(resultSet
						.getLong("ID_SOLICITUDCREACION"));
				solicitudCreacion.setEstado(resultSet.getString("ESTADO"));
				solicitudCreacion.setFechaCreacion(resultSet
						.getDate("FECHACREACION"));
				solicitudCreacion.setFechaEjecucionbf(resultSet
						.getDate("FECHAEJECUCIONBF"));
				solicitudCreacion.setNombreArchivo(resultSet
						.getString("NOMBREARCHIVO"));
				solicitudCreacion.setUsuarioCreacion(resultSet
						.getString("USUARIOCREACION"));
				solicitudCreacion.setSemaforo(resultSet.getString("SEMAFORO"));
				solicitudCreacion.setCuentascreadas(resultSet
						.getLong("CUENTASCREADAS"));
				solicitudCreacion.setNroRegistros(resultSet
						.getBigDecimal("NROREGISTROS"));
				solicitudCreacion
						.setMoneda(new Moneda(Long.valueOf(resultSet
								.getString("ID_MONEDA")), resultSet
								.getString("MONEDA")));
				solicitudCreacion.setTipoCuenta(new TipoCuenta(Long
						.valueOf(resultSet.getString("ID_TIPOCUENTA")),
						resultSet.getString("TIPOCUENTA")));
				solicitudCreacionList.add(solicitudCreacion);

			}
		} catch (SQLException e) {
			logger.error(e, e.fillInStackTrace());
			throw new DomainException(e);
		} finally {
			try {
				cal.getConnection().close();
				cal.close();
			} catch (SQLException e) {

				e.printStackTrace();
			}

		}
		return solicitudCreacionList;
	}

	@SuppressWarnings("finally")
	@Override
	public List<Empleado> listarDetalleSolicitudCreacion(
			BigInteger codigoEmpresa, BigInteger codigoSolicitudCreacion)
			throws DomainException {
		ResultSet resultSet = null;
		CallableStatement cal = invokeStoreProcedureCallable(
				USP_LIS_DET_SOLIC_CREACION, codigoEmpresa.longValue() + "",
				codigoSolicitudCreacion.longValue() + "", new OutParameter(
						OracleTypes.CURSOR));
		List<Empleado> empleadoList = new ArrayList<Empleado>();

		try {
			resultSet = (ResultSet) cal.getObject(3);
			while (resultSet.next()) {
				Empleado empleado = new Empleado();
				TipoDocumento tipoDocumento = new TipoDocumento();
				empleado.setIdEmpleado(resultSet.getLong("ID_EMPLEADO"));
				tipoDocumento.setIdTipodocumento(resultSet
						.getLong("ID_TIPODOCUMENTO"));
				tipoDocumento.setDescripcion(resultSet
						.getString("TIPODOCUMENTO"));
				empleado.setTipodocumento(tipoDocumento);
				empleado.setNrodocumento(resultSet.getString("NRODOCUMENTO"));
				empleado.setNrocuenta(resultSet.getString("NROCUENTA"));
				Moneda moneda = new Moneda();
				moneda.setIdMoneda(resultSet.getInt("ID_MONEDA"));
				moneda.setDescripcion(resultSet.getString("MONEDA"));
				empleado.setMoneda(moneda);
				empleado.setApellidonombre(resultSet
						.getString("APELLIDONOMBRE"));
				empleado.setEstado(resultSet.getString("ESTADO"));
				empleado.setFechanacimiento(resultSet
						.getDate("FECHANACIMIENTO"));
				empleadoList.add(empleado);
			}
		} catch (SQLException e) {
			e.printStackTrace();
			logger.error(e, e.fillInStackTrace());
			throw new DomainException(e);
		} finally {
			try {
				cal.getConnection().close();
				cal.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
			return empleadoList;
		}

	}

}
